上篇分析到了SimpleExecutor
接口, 这个接口中的doUpdate,doQuery
方法是Executor
体系中最终的实现。 本节分析下Executor
中具体的逻辑
1. SimpleExecutor
接口
1.1 doUpdate, doQuery
的实现
1 | public int doUpdate(MappedStatement ms, Object parameter) throws SQLException { |
上面的3行代码就是由BaseExecutor
类中的query,update
调用到SimpleExecutor
的方法。可以看到对于doUpdate,doQuery
两个方法都有如下几步:
- 从
Configuration
类中生成一个对应的StatementHandler
- 获取一个JDBC连接,然后调用
handler
的prepare
方法,该方法事实上是调用的connection.createStatement
创建的连接。handler接口下面讲述 - 然后调用
handler
的对应query,update
方法 - 再返回数据给
BaseExecutor
中的query, update
方法当中
显而易见,StatementHandler
接口实际承担了Statement
的生成以及query, update
的操作。
2. StatementHandler
接口
2.1 整体结构
2.2 调用分析
2.2.1 介绍
StatementHandler
接口的继承链与Executor
接口的非常相似,都是包含一个委托类,一个抽象基类以及3哥实现类。调用方式有些许不同:
- 对
StatementHandler
的query, update
的调用最终会传到SimpleStatementHandler, PrepareStementHandler, CallableStatementHandler
中的一个 RoutingStatementHandler
的构造函数起到了工厂的作用,它根据statement
的类型决定生成SimpleStatementHandler, PrepareStementHandler, CallableStatementHandler
哪一个实例。
下面分别看下这3个类的实现方式
2.2.2 SimpleStatementHandler
1 | public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { |
2.2.3 PrepareStementHandler
1 | public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { |
2.2.4 CallableStementHandler
1 | public int update(Statement statement) throws SQLException { |
2.2.5 总结
上面3个类结合JDBC的API一看就知道是怎么回事,这3个类就是对JDBC的SQL执行的一层封装。
所以到目前为止,我们看到了SqlSession
接口调用mapper xml的执行链:sqlsession -> executor -> statementhandler,最终会根据具体SQL的类型调用JDBC的三种statement类型来处理实际业务。 MappedStatement
封装了mapper xml中声明的每一个SQL。 StatementHandler
封装了JDBC操作。 Executor
封装了mapper xml缓存以及执行,批量执行。
合理的策略模式、抽象基类 非常完美的阐释了java中的OO思维。